package com.atguigu.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 测试Car类的反射机制
 */
public class TestCar {
    //1.获取Class对象多种方式
    @Test
    public void test01() throws Exception {
        //1 类名.class
        Class<Car> clazz1 = Car.class;
        //2 对象.getClass()
        Class clazz2 = new Car().getClass();

        //3 Class.forName("全路径")
        Class clazz3 = Class.forName("com.atguigu.reflect.Car");
        //实例化
        Car car = (Car) clazz3.getDeclaredConstructor().newInstance();
        System.out.println(car);
    }

    //2.获取构造方法
    @Test
    public void test02() throws Exception {
        Class clazz = Car.class;
        //获取所有构造
        //getConstructors()获取所有public的构造方法
        //Constructor[] constructors = clazz.getConstructors();
        //getDeclaredConstructors()获取所有构造方法,包括public和private
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor c : constructors) {
            System.out.println("方法名称: " + c.getName() + " 参数个数:" + c.getParameterCount());
        }
        //指定有参数构造创建对象
        //1 构造public
       // Constructor c1 = clazz.getConstructor(String.class, int.class, String.class);
        //Car car1=(Car)c1.newInstance("法拉利", 2023, "红色");
        //System.out.println(car1);
        //2 构造private
        Constructor c2 = clazz.getDeclaredConstructor(String.class, int.class, String.class);
        c2.setAccessible(true);
        Car car2=(Car)c2.newInstance("捷达", 2023, "红色");
        System.out.println(car2);

    }
    //3.获取属性
    @Test
    public void test03() throws Exception {
        Class clazz = Car.class;
        Car car=(Car) clazz.getDeclaredConstructor().newInstance();
        //获取所有public属性
        Field[] fields = clazz.getFields();
        //获取所有属性(包含私有)
        Field[] declaredFields = clazz.getDeclaredFields();
        for(Field f1:fields){
            System.out.println("public属性: "+f1.getName());
        }
        for(Field f2:declaredFields){
            if(f2.getName().equals("name")){
                //设置允许进行访问
                f2.setAccessible(true);
                f2.set(car,"问界");
            }
            System.out.println("所有属性: "+f2.getName());
            System.out.println(car);
        }
    }

    //4.获取方法
    @Test
    public void test04() throws Exception {
Car car=new Car("奔驰",10,"黑色");
Class clazz=car.getClass();
        //public方法
        Method[] methods=clazz.getMethods();
        for(Method m:methods){
            System.out.println("public方法: "+m.getName());
            //执行方法 toString
            if(m.getName().equals("toString")){
             String invoke= (String) m.invoke(car);
             System.out.println("toString方法执行了:"+invoke);
            }

        }

        //private 方法
        Method[] methodsAll=clazz.getDeclaredMethods();
        for (Method m : methodsAll) {
            //执行方法 run
            if (m.getName().equals("run")) {
                m.setAccessible(true);
                m.invoke(car);
            }
        }
    }
}
